<template>
  <div class="ansible-adhoc">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">
          <span class="icon">⚡</span>
          <span>Ad-hoc执行</span>
        </h1>
        <p class="page-subtitle">快速执行Ansible命令，实时查看执行结果</p>
      </div>
    </div>

    <!-- 快速执行区域 -->
    <div class="execution-section">
      <div class="section-header">
        <span class="header-icon">⚡</span>
        <span class="header-title">快速执行</span>
      </div>

      <div class="execution-form">
        <!-- 第一行：配置选择 -->
        <div class="form-row">
          <div class="form-group">
            <label class="form-label">
              <span class="label-icon">🔧</span>
              <span>选择Ansible配置</span>
            </label>
            <select v-model="selectedInventory" class="form-select">
              <option value="">请选择Ansible配置</option>
              <option v-for="inv in inventories" :key="inv.id" :value="inv.id">
                {{ inv.name }}
              </option>
            </select>
          </div>

          <div class="form-group">
            <label class="form-label">
              <span class="label-icon">🔐</span>
              <span>选择主机凭据</span>
            </label>
            <select v-model="selectedCredential" class="form-select">
              <option value="">请选择主机凭据</option>
              <option v-for="cred in credentials" :key="cred.id" :value="cred.id">
                {{ cred.name }} ({{ getCredTypeText(cred.credential_type) }})
              </option>
            </select>
          </div>
        </div>

        <!-- 第二行：模块和参数 -->
        <div class="form-row">
          <div class="form-group">
            <label class="form-label">
              <span class="label-icon">📦</span>
              <span>选择模块</span>
            </label>
            <select v-model="selectedModule" class="form-select" @change="updateCommand">
              <option value="">选择模块或直接输入命令</option>
              <option value="ping">ping - 测试连接</option>
              <option value="shell">shell - 执行Shell命令</option>
              <option value="command">command - 执行命令</option>
              <option value="copy">copy - 复制文件</option>
              <option value="file">file - 管理文件</option>
              <option value="service">service - 管理服务</option>
              <option value="yum">yum - 安装软件包</option>
              <option value="apt">apt - 安装软件包(Debian)</option>
              <option value="user">user - 管理用户</option>
              <option value="group">group - 管理组</option>
              <option value="setup">setup - 收集系统信息</option>
            </select>
          </div>

          <div class="form-group">
            <label class="form-label">
              <span class="label-icon">⚙️</span>
              <span>模块参数</span>
            </label>
            <input 
              v-model="moduleArgs" 
              type="text" 
              class="form-input"
              :placeholder="getArgsPlaceholder()"
              @input="updateCommand"
            />
          </div>
        </div>

        <!-- 第三行：主机模式 -->
        <div class="form-row">
          <div class="form-group full-width">
            <label class="form-label">
              <span class="label-icon">🎯</span>
              <span>目标主机模式</span>
            </label>
            <input 
              v-model="hostPattern" 
              type="text" 
              class="form-input"
              placeholder="all, web*, db[0:2], 或具体主机名"
              @input="updateCommand"
            />
          </div>
        </div>

        <!-- 命令预览 -->
        <div class="command-preview">
          <div class="preview-header">
            <span class="preview-icon">💻</span>
            <span class="preview-title">命令预览</span>
          </div>
          <div class="preview-content">
            <code>{{ commandPreview }}</code>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="action-buttons">
          <button 
            class="btn btn-primary" 
            @click="executeAdhoc"
            :disabled="isExecuting || !canExecute"
          >
            <span class="btn-icon">{{ isExecuting ? '⏳' : '▶️' }}</span>
            <span>{{ isExecuting ? '执行中...' : '立即执行' }}</span>
          </button>
          <button 
            class="btn btn-secondary" 
            @click="validateCommand"
            :disabled="!canExecute"
          >
            <span class="btn-icon">✓</span>
            <span>验证命令</span>
          </button>
          <button class="btn btn-outline" @click="clearForm">
            <span class="btn-icon">🔄</span>
            <span>清空</span>
          </button>
        </div>
      </div>
    </div>

    <!-- 执行结果区域 -->
    <div v-if="executionResult" class="result-section">
      <div class="section-header">
        <span class="header-icon">📊</span>
        <span class="header-title">执行终端</span>
        <div class="header-actions">
          <button class="action-btn" @click="copyResult" title="复制">
            <span>📋</span>
            <span>复制</span>
          </button>
          <button class="action-btn" @click="downloadResult" title="下载">
            <span>💾</span>
            <span>下载结果</span>
          </button>
        </div>
      </div>

      <div class="result-content">
        <!-- 执行状态 -->
        <div class="result-status" :class="'status-' + executionResult.status">
          <span class="status-icon">
            {{ executionResult.status === 'success' ? '✅' : 
               executionResult.status === 'failed' ? '❌' : '⏳' }}
          </span>
          <span class="status-text">
            {{ executionResult.status === 'success' ? '执行成功' : 
               executionResult.status === 'failed' ? '执行失败' : '执行中' }}
          </span>
        </div>

        <!-- 标准输出 -->
        <div v-if="executionResult.stdout" class="output-section">
          <h4 class="output-title">📤 标准输出</h4>
          <pre class="output-text">{{ executionResult.stdout }}</pre>
        </div>

        <!-- 错误输出 -->
        <div v-if="executionResult.stderr" class="output-section error">
          <h4 class="output-title">⚠️ 错误输出</h4>
          <pre class="output-text">{{ executionResult.stderr }}</pre>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import api from '@/services/api'

// 数据状态
const inventories = ref([])
const credentials = ref([])
const selectedInventory = ref('')
const selectedCredential = ref('')
const selectedModule = ref('')
const moduleArgs = ref('')
const hostPattern = ref('all')
const commandPreview = ref('ansible all -m ping')
const isExecuting = ref(false)
const executionResult = ref(null)

// 计算属性
const canExecute = computed(() => {
  return selectedInventory.value && selectedCredential.value && hostPattern.value
})

// 加载数据
const loadData = async () => {
  try {
    const [invData, credData] = await Promise.all([
      api.getInventories(),
      api.getCredentials()
    ])
    
    inventories.value = Array.isArray(invData) ? invData : (invData.results || [])
    credentials.value = Array.isArray(credData) ? credData : (credData.results || [])
  } catch (error) {
    console.error('加载数据失败:', error)
    alert('❌ 加载数据失败: ' + (error.response?.data?.error || error.message))
  }
}

// 获取凭据类型文本
const getCredTypeText = (type) => {
  const map = {
    'ssh_password': '🔐密码',
    'ssh_key': '🔑密钥',
    'vault': '🔒Vault'
  }
  return map[type] || type
}

// 获取参数占位符
const getArgsPlaceholder = () => {
  const placeholders = {
    'ping': '不需要参数',
    'shell': '例如: ls -la',
    'command': '例如: uptime',
    'copy': '例如: src=/tmp/file dest=/tmp/file',
    'file': '例如: path=/tmp/test state=touch',
    'service': '例如: name=nginx state=restarted',
    'yum': '例如: name=nginx state=present',
    'apt': '例如: name=nginx state=present',
    'user': '例如: name=testuser state=present',
    'group': '例如: name=testgroup state=present',
    'setup': '不需要参数'
  }
  return placeholders[selectedModule.value] || '输入模块参数'
}

// 更新命令预览
const updateCommand = () => {
  const inv = inventories.value.find(i => i.id === selectedInventory.value)
  const inventoryPath = inv?.inventory_path || '/etc/ansible/hosts'
  
  let cmd = `ansible ${hostPattern.value || 'all'}`
  
  if (selectedModule.value) {
    cmd += ` -m ${selectedModule.value}`
    if (moduleArgs.value) {
      cmd += ` -a "${moduleArgs.value}"`
    }
  } else if (moduleArgs.value) {
    cmd += ` -m shell -a "${moduleArgs.value}"`
  } else {
    cmd += ` -m ping`
  }
  
  cmd += ` -i ${inventoryPath}`
  
  commandPreview.value = cmd
}

// 执行Ad-hoc命令
const executeAdhoc = async () => {
  if (!canExecute.value) {
    alert('❌ 请完善执行配置')
    return
  }
  
  isExecuting.value = true
  executionResult.value = { status: 'running', stdout: '正在执行...', stderr: '' }
  
  try {
    const module = selectedModule.value || 'shell'
    const args = moduleArgs.value || (selectedModule.value === 'ping' ? '' : 'echo "No command specified"')
    
    const result = await api.executeAdhoc({
      inventory: selectedInventory.value,
      credential: selectedCredential.value,
      module: module,
      args: args,
      host_pattern: hostPattern.value
    })
    
    executionResult.value = {
      status: result.success ? 'success' : 'failed',
      stdout: result.stdout || '',
      stderr: result.stderr || ''
    }
    
    // 执行结果已显示在界面上，不需要额外弹窗
    console.log('Ad-hoc命令执行完成:', result.success ? 'success' : 'failed')
  } catch (error) {
    console.error('执行失败:', error)
    const errorMsg = error.response?.data?.error || error.message
    executionResult.value = {
      status: 'failed',
      stdout: '',
      stderr: errorMsg
    }
    // 错误信息已显示在结果面板中，不需要弹窗
  } finally {
    isExecuting.value = false
  }
}

// 验证命令
const validateCommand = () => {
  if (!canExecute.value) {
    alert('❌ 请完善执行配置')
    return
  }
  
  alert(`✅ 命令验证通过！\n\n将执行命令:\n${commandPreview.value}`)
}

// 清空表单
const clearForm = () => {
  selectedModule.value = ''
  moduleArgs.value = ''
  hostPattern.value = 'all'
  executionResult.value = null
  updateCommand()
}

// 复制结果
const copyResult = () => {
  if (!executionResult.value) return
  const text = (executionResult.value.stdout || '') + '\n' + (executionResult.value.stderr || '')
  navigator.clipboard.writeText(text).then(() => {
    alert('✅ 已复制到剪贴板')
  })
}

// 下载结果
const downloadResult = () => {
  if (!executionResult.value) return
  const text = (executionResult.value.stdout || '') + '\n' + (executionResult.value.stderr || '')
  const blob = new Blob([text], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = 'adhoc_result.txt'
  a.click()
  URL.revokeObjectURL(url)
}

// 生命周期
onMounted(() => {
  loadData()
  updateCommand()
})
</script>

<style scoped>
@import '../styles/ansible-theme.css';

/* 区域样式 */
.execution-section,
.result-section {
  background: var(--color-bg-secondary);
  border: 2px solid transparent;
  background-image: 
    linear-gradient(#fff, #fff),
    linear-gradient(135deg, rgba(255, 107, 157, 0.3), rgba(196, 113, 237, 0.3));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  border-radius: 16px;
  padding: 24px;
  margin-bottom: 24px;
  box-shadow: 0 4px 16px rgba(255, 107, 157, 0.1);
}

.section-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 2px solid transparent;
  border-image: linear-gradient(90deg, #ff6b9d, #c471ed, #12cad6) 1;
}

.header-icon {
  font-size: 24px;
}

.header-title {
  font-size: 20px;
  font-weight: 700;
  background: linear-gradient(135deg, #ff6b9d, #c471ed);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.header-actions {
  margin-left: auto;
  display: flex;
  gap: 8px;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  background: linear-gradient(135deg, rgba(255, 107, 157, 0.1), rgba(196, 113, 237, 0.1));
  border: 2px solid rgba(255, 107, 157, 0.3);
  border-radius: 12px;
  color: #ff6b9d;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  transition: all 0.3s ease;
}

.action-btn:hover {
  background: linear-gradient(135deg, rgba(255, 107, 157, 0.2), rgba(196, 113, 237, 0.2));
  border-color: #ff6b9d;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(255, 107, 157, 0.3);
}

/* 表单样式 */
.execution-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.form-group.full-width {
  grid-column: 1 / -1;
}

/* 命令预览 */
.command-preview {
  background: var(--color-bg-primary);
  border: 2px solid var(--color-accent-blue);
  border-radius: 12px;
  padding: 16px;
}

.preview-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  color: var(--color-accent-blue);
  font-size: 14px;
  font-weight: 600;
}

.preview-icon {
  font-size: 18px;
}

.preview-content {
  padding: 12px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 8px;
  overflow-x: auto;
}

.preview-content code {
  color: var(--color-accent-blue);
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 13px;
  white-space: pre-wrap;
  word-break: break-all;
}

/* 按钮样式 */
.action-buttons {
  display: flex;
  gap: 12px;
  padding-top: 8px;
}

.btn-icon {
  font-size: 16px;
}

.btn-secondary {
  background: linear-gradient(135deg, rgba(18, 202, 214, 0.2), rgba(18, 202, 214, 0.1));
  border: 2px solid var(--color-accent-blue);
  color: var(--color-accent-blue);
}

.btn-secondary:hover:not(:disabled) {
  background: linear-gradient(135deg, rgba(18, 202, 214, 0.3), rgba(18, 202, 214, 0.2));
  border-color: var(--color-accent-blue);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(18, 202, 214, 0.3);
}

.btn-secondary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-outline {
  background: transparent;
  border: 2px solid rgba(255, 107, 157, 0.3);
  color: #ff6b9d;
}

.btn-outline:hover {
  background: rgba(255, 107, 157, 0.1);
  border-color: #ff6b9d;
  transform: translateY(-2px);
}

/* 结果区域 */
.result-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.result-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  border-radius: 12px;
  font-size: 16px;
  font-weight: 600;
}

.result-status.status-success {
  background: linear-gradient(135deg, rgba(81, 207, 102, 0.2), rgba(81, 207, 102, 0.1));
  border: 2px solid var(--color-accent-success);
  color: var(--color-accent-success);
}

.result-status.status-failed {
  background: linear-gradient(135deg, rgba(255, 107, 107, 0.2), rgba(255, 107, 107, 0.1));
  border: 2px solid #ff6b6b;
  color: #ff6b6b;
}

.result-status.status-running {
  background: linear-gradient(135deg, rgba(255, 107, 157, 0.2), rgba(196, 113, 237, 0.1));
  border: 2px solid var(--color-accent-pink);
  color: var(--color-accent-pink);
}

.status-icon {
  font-size: 24px;
}

.output-section {
  background: var(--color-bg-primary);
  border: 2px solid var(--color-border);
  border-radius: 12px;
  padding: 16px;
}

.output-section.error {
  border-color: #ff6b6b;
}

.output-title {
  color: var(--color-accent-pink);
  margin: 0 0 12px 0;
  font-size: 14px;
  font-weight: 600;
}

.output-section.error .output-title {
  color: #ff6b6b;
}

.output-text {
  background: rgba(0, 0, 0, 0.2);
  padding: 12px;
  border-radius: 8px;
  color: var(--color-accent-blue);
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 13px;
  line-height: 1.6;
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  margin: 0;
}

.output-section.error .output-text {
  color: #ff6b6b;
}

/* 响应式 */
@media (max-width: 768px) {
  .form-row {
    grid-template-columns: 1fr;
  }
  
  .action-buttons {
    flex-direction: column;
  }
  
  .btn {
    width: 100%;
    justify-content: center;
  }
}
</style>
